/**
 * *****************************************************************
 * @file    adt3102_tx.h
 * @author  WuHao(hwu@andartechs.com.cn)
 * @version 1.0.0
 * @date    2020-11-09
 * @brief   
 *                 Copyright (c) 2020, Andar Technologies Inc.
 *                           www.andartechs.com 
 *
 * *****************************************************************
 */
#ifndef __TX_H
#define __TX_H


/*------------------------------ include -------------------------------------*/
#include "adt3102_type_define.h"


/*------------------------------ define --------------------------------------*/
/*
MODE_INTER    : 20G to internal doubler
MODE_EXTERN   : 20G from external source
MODE_CASCADED : 20G to internal doubler and output other chip
MODE_TEST     : 20G output test port
*/
#define MODE_INTER      00
#define MODE_EXTERN     01
#define MODE_CASCADED   10
#define MODE_TEST       11

/*
POWER_ON : power on 0 valid
POWER_DOWN : power down 1 valid
*/
#define POWER_ON    0
#define POWER_DOWN  1

/* BB_LDO_xPy :set baseband ldo voltage x.yv */
#define BB_LDO_1P8  0
#define BB_LDO_2P0  1
#define BB_LDO_2P2  2
#define BB_LDO_2P5  3

/* DVDDxPy_HP :set VDD ldo voltage x.yv */
#define DVDD1P2_HP  0
#define DVDD1P1_HP  1
#define DVDD1P3_HP  2
#define DVDD1P4_HP  3

/* DVDD_LP :set VDD ldo voltage */
#define DVDD1P2_LP  0
#define DVDD0P7_LP  1
#define DVDD0P75_LP 2
#define DVDD0P8_LP  3
#define DVDD0P85_LP 4
#define DVDD1P0_LP  5
#define DVDD1P1_LP  6
#define DVDD1P3_LP  7

/* PLLN_VCO_LDO_xPy : set PLLN VCO LDO voltage x.yv */
#define PLLN_VCO_LDO_1P8    0
#define PLLN_VCO_LDO_2P0    1
#define PLLN_VCO_LDO_2P2    2
#define PLLN_VCO_LDO_2P5    3

/* PLLN_PLL_LDO_xPy : set PLLN PLL LDO voltage x.yv */
#define PLLN_PLL_LDO_1P8    0
#define PLLN_PLL_LDO_2P0    1
#define PLLN_PLL_LDO_2P2    2
#define PLLN_PLL_LDO_2P5    3

/*
DATA_SAMPLE_MODULE : fmcw_en select from data_sample module
REGISTER : fmcw_en select from register
*/
#define DATA_SAMPLE_MODULE 1
#define REGISTER           0

/*
SINGLE_MODE : chirp_single_mode is single mode
CONTINUE_MODE : chirp_single_mode is continue mode
*/
#define SINGLE_MODE   1
#define CONTINUE_MODE 0

/*
PAx_ENABLE :  pax enable
PAx_DISABLE : pax disable
*/
#define PA0_ENABLE  1
#define PA0_DISABLE 0
#define PA1_ENABLE  1
#define PA1_DISABLE 0

/* TEMPxUA :kc_bottom<1:0>: Mini bias setting@temp<-20c,'00' 20uA, '01' 30uA,'10' 40u,'11' 50uA. */
#define TEMP20UA    0
#define TEMP30UA    1
#define TEMP40UA    2
#define TEMP50UA    3

/* KC1_XxPT :kc1_reg: bias0~11 temp coefficient control, '000' 1x PT current rate, '111' 3x PT rate. */
#define KC1_X1PT    0
#define KC1_X3PT    7

/* KC2_XxPT :kc2_reg: bias12~23 temp coefficient control, '000' 1x PT current rate, '111' 3x PT rate. */
#define KC2_X1PT    0
#define KC2_X3PT    7


/*----------------------------- function --------------------------------------*/
/*-----------------------PLLI-----------------------------*/
/**
 * @brief   plli vco Ldo setting, plli pll vco ldo is enable default, cloes through FSM.
 * @param   plliVcoLdoEnable: plli Vco Ldo Enable.
 * @param   plliPllLdoEnable: plli Pll Ldo Enable.
 * @return  None.
 * @note
 */
void plliLDOEnable(int32 plliVcoLdoEnable, int32 plliPllLdoEnable);

/**
 * @brief   plli dac setting.
 * @param   None.
 * @return  None.
 * @note
 */
void plliDacSetting(void);

/**
 * @brief   plli setting.
 * @param   plliVcoEn: ENABLE/DISABLE.
 * @return  None.
 * @note
 */
void plliConfig(int32 plliVcoEn);

/*-----------------------PLLN-----------------------------*/
/**
 * @brief   plln vco config. selection:
 *          PLLN_VCO_LDO_1P8     PLLN_VCO_LDO_2P2
 *          PLLN_VCO_LDO_2P0     PLLN_VCO_LDO_2P5
 * @param   pllnVcoLdoEnable: enable VCO LDO.
 * @param   pllnVcoLdo: adjust avdd_VCO for PLL VCO
 * @return  None.
 * @note
 */
void pllnVcoConfig(int32 pllnVcoLdoEnable, int32 pllnVcoLdo);

/**
 * @brief   plln pll config.selection:
 *          PLLN_VCO_LDO_1P8     PLLN_VCO_LDO_2P2
 *          PLLN_VCO_LDO_2P0     PLLN_VCO_LDO_2P5
 * @param   pllnPllLdoEnable: enable PLLN LDO.
 * @param   pllnPllLdo: adjust avdd for PLLN.
 * @param   pllnEnBias: plln enable bias.
 * @return  None.
 * @note
 */
void pllnPllConfig(int32 pllnPllLdoEnable, int32 pllnPllLdo, int32 pllnEnBias);

/**
 * @brief   plln dac setting.
 * @param   None.
 * @return  None.
 * @note
 */
void pllnDacSetting(void);

/**
 * @brief   plln config.
 * @param   vcoEn: ENABLE/DISABLE.
 * @return  None.
 * @note
 */
void pllnConfig(int32 vcoEn);

/**
 * @brief   plln vco config.
 * @param   vcoEn: ENABLE/DISABLE.
 * @return  None.
 * @note
 */
void pllnVcoEnable(int32 vcoEn);

/*------------------------LDO-----------------------------*/
/**
 * @brief   adjust LDO output, '00' 1.8v, '01' 2v, '10' 2.2v, '11' 2.5v.
 * @param   bb1Enable: baseband1 ldo enable.
 * @param   bb1Adjust: adjust baseband1 LDO output.
 * @param   bb2Enable: baseband2 ldo enable.
 * @param   bb2Adjust: adjust baseband2 LDO output.
 * @return  None.
 * @note
 */
void baseband18LDO(int32 bb1Enable, int32 bb1Adjust, int32 bb2Enable, int32 bb2Adjust);

/**
 * @brief   Adjust the out of the LDO_1p2_HP, '00' 1.2v, '01' 1.1v, '10' 1.3v, '11' 1.4v.
 *          selection:  POWER_ON        DVDD1P2_HP DVDD1P3_HP
 *                      POWER_OFF       DVDD1P1_HP DVDD1P4_HP
 * @param   powerOnDown: usually we do not turn off vdd.
 * @param   dvdd12Adjust: Adjust the out of the LDO_1p2_HP.
 * @return  None.
 * @note
 */
void dvdd12HpLDO(int32 powerOnDown, int32 dvdd12Adjust);
void dvdd12LpLDO(int32 powerOnDown, int32 dvdd12Adjust);

/*-----------------------Mixer---------------------------*/
/**
 * @brief   o_reg:FMCW buffer mode.
 *          selection:  MODE_INTER    : 20G to internal doubler
 *                      MODE_EXTERN   : 20G from external source
 *                      MODE_CASCADED : 20G to internal doubler and output other chip
 *                      MODE_TEST     : 20G output test port
 * @param   fmcwMode: 00': int32 mode, '01' external mode, 
 *                      '10' cascaded mode, '11' test mode.
 * @return  None.
 * @note
 */
void fmcwModeSel(int32 fmcwMode);

/**
 * @brief   20G buffer and doubler enable.
 * @param   buffer20gEn: 20G buffer enable.
 * @param   doublerEn: doubler enable.
 * @return  None.
 * @note
 */
void rfbuff20G(int32 buffer20gEn, int32 doublerEn);

/**
 * @brief   about 80G buffer dac enable.
 * @param   biasdb77G: ib_db77.
 * @param   biasBuff38: ib_buf38.
 * @param   biasDb38: ib_db38.
 * @param   bias2Buff20G: 20G buf bias2.
 * @param   biasbuff20G: 20G buf.
 * @param   txBuff1To4: buf_1to4, tx loop.
 * @param   loBuff1To4: buf_1to4, lo loop.
 * @param   rxBuff1To4: buf_1to4, rx loop.
 * @return  None.
 * @note
 */
void bias20GTo80G(int32 biasdb77G, int32 biasBuff38, int32 biasDb38, int32 bias2Buff20G, 
                  int32 biasbuff20G, int32 txBuff1To4, int32 loBuff1To4, int32 rxBuff1To4);

/**
 * @brief   enable for dac<9:24> and bias1 power down, '0' enable, '1' disable..
 * @param   dacEnable: enable for dac<9:24>.
 * @param   Bias1PowerDown: bias1 power down, '0' enable, '1' disable.
 * @return  None.
 * @note
 */
void dacEnBias1Pd(int32 dacEnable, int32 Bias1PowerDown);
void biasPowerdector(int32 biasPowerDector);

/**
 * @brief   bist bias setting.
 * @param   biasBistIptat0: bias1_din18:DAC18, bist IPTAT<1>.
 * @param   biasBistIptat1: bias1_din17:DAC17, bist IPTAT<0>.
 * @param   biasBist0: bias2_din18:DAC15 data, Bist bias<1>.
 * @param   biasBist1: bias2_din17:DAC14 data, Bist bias<0>.
 * @return  None.
 * @note
 */
void biasBist(int32 biasBistIptat0, int32 biasBistIptat1, int32 biasBist0, int32 biasBist1);
void biasGpadc(int32 gpadcBias1test, int32 gpadcBias2test, int32 gpadcBias);

/**
 * @brief   77G buffer enable.
 * @param   stage1Buff77G: 77G buffer 1st stage enable.
 * @param   tx0BufferEn77G: tx0 buffer enable.
 * @param   tx1BufferEn77G: tx1 buffer enable.
 * @param   rx0BufferEn77G: rx0 buffer enable.
 * @param   rx1BufferEn77G: rx1 buffer enable.
 * @return  None.
 * @note
 */
void rfBuff77GEnable(int32 stage1Buff77G, int32 tx0BufferEn77G, int32 tx1BufferEn77G,
                    int32 rx0BufferEn77G, int32 rx1BufferEn77G);


/*-------------------------PA-----------------------------*/
/**
 * @brief   control pa enable.
 * @param   pa0Enable: channel0 DAC bias1.
 * @param   pa1Enable: channel0 DAC bias2.
 * @return  None.
 * @note
 */
void txPaEnable(int32 pa0Enable, int32 pa1Enable);

/**
 * @brief   control dac pa bias.
 * @param   pa0Bias: channel0 PA bias1.
 * @param   pa1Bias: channel0 PA bias2.
 * @return  None.
 * @note
 */
void txPaBias(int32 pa0Bias, int32 pa1Bias);

/**
 * @brief   phase shifter data setting.
 * @param   ps_ip: phase shifter i posedge.
 * @param   ps_in: phase shifter i negedge.
 * @param   ps_qp: phase shifter q posedge.
 * @param   ps_qn: phase shifter q negedge.
 * @return  None.
 * @note
 */
void rfPhaseShift(int32 ps_ip, int32 ps_in, int32 ps_qp, int32 ps_qn);
void rfPhaseShiftLUT(int32 ch0_idx, int32 ch1_idx);

/*------------------------FMCW----------------------------*/
/**
 * @brief   adjust plli vco switch, lock plli at 1G.
 * @param   None.
 * @return  None.
 * @note
 */
void plliLock(void);

/**
 * @brief   vtune read.
 *          -> start frequence single lock
            -> end frequence single lock
 * @param   None.
 * @return  float.
 * @note
 */
float vtuneRead(void);

/**
 * @brief   adjust plln lock.
 * @param   fstart: FSTART.
 * @param   fm: FM.
 * @return  None.
 * @note
 */
void pllnLock(float fstart, uint32 fm);

/**
 * @brief   adjust plln lock with returned status and fstart.
 * @param   freqStart: pointer to fstart.
 * @param   fm: FM.
 * @param   chirpNumber:  chirpNumber.
 * @return  uint8:   the plln lock status
 * @note
 */
uint8 pllnLockM(float *freqStart, uint32 fm, uint32 chirpNumber);

/**
 * @brief   temperature compensation.
 * @param   miniBais: .
 * @param   kc1Reg: .
 * @param   kc2Reg: .
 * @return  None.
 * @note
 */
void temperatureCompensation(uint32 miniBais, uint32 kc1Reg, uint32 kc2Reg);

/**
 * @brief   The following is the parameter configuaration of vco output(sweep wave).
 *   |                /|\                    /|\        |            /|\
 *   |               / | \                  / | \       |           / | \
 *   |              /  |  \                /  |  \      |          /  |  \
 *   |             /   |   \              /   |   \    FM         /   |   \
 *   |            /    |    \            /    |    \    |        /    |    \
 *   |           /     |     \          /     |     \   |       /     |     \
 *   |          /      |      \        /      |      \  |      /      |      \
 *   |[fstart] /       |       \      /       |       \ |     /       |       \
_*___|________/________|________\____/________|________\|____/________|________\
 *   |        [  t0    ][  t1   ][t2][  t0    ][   t1   ][t2]
 *   |        [    Chirp1 cycle     ][    Chirp2 cycle  ]
 * @param   fstart:     GHz  start frequence.
 * @param   fm:         MHz  bandwidth.
 * @param   num_step:   us   chir p0 rise time.
 * @param   t0:         us   chirp1 rise time.
 * @param   t1:         us   chirp1 rise time.
 * @param   t2:         us   chirp1 rise time.
 * @param   chirpNumber: FMCW chirp number TX (Chirp1 cycle,Chirp2 cycle......).
 * @return  None.
 * @note    1,t1+t2+T3 = n*(120ns)
            2,single frequency mode setting: FM=0;
            3,t1<500us,t2>10us
 */
void fmcwConfig(float fstart,uint32 fm,uint32 t0,uint32 t1,uint32 t2,uint32 chirpNumber);

/**
 * @brief   The following is the parameter configuaration of vco output(sweep wave).
 *                          fmSaw0                                              fmSaw0                                                                               _
 *   ?                        /|\                                                 /|\                                
 *   |                      /  | \            fmSaw1             |              /  | \            fmSaw1             
 *   |                    /    |  \            /|\               |            /    |  \            /|\               
 *   |                  /      |   \          / | \              |          /      |   \          / | \              
 *   |                /        |    \        /  |  \             |        /        |    \        /  |  \             
 *   |              /          |     \      /   |   \            |      /          |     \      /   |   \            
 *   |            /            |      \    /    |    \           |    /            |      \    /    |    \           
 *   |[fstart]  /              |       \  /     |     \          |  /              |       \  /     |     \          
_*___|________/________________|________\/______|______\_________|/________________|________\/______|______\_________
 *   |        [    t0Saw0      ][t1Saw0 ][t0Saw1][t1Saw1][  t2  ]|
 *   |        [    Chirp1 cycle                                 ][    Chirp1 cycle                                 ]
 *   |                                                           |
 * @param   fstart:     GHz  start frequence.
 * @param   fm:         MHz  bandwidth.
 * @param   num_step:   us   chir p0 rise time.
 * @param   t0Saw0:     us   saw0 rise time.
 * @param   t1Saw0:     us   saw0 fall time.
 * @param   t0Saw0:     us   saw1 rise time.
 * @param   t1Saw1:     us   saw1 fall time.
 * @param   t2:         us   reset time.
 * @param   chirpNumber: FMCW chirp number TX (Chirp1 cycle,Chirp2 cycle......).
 * @return  None.
 * @note    1. (t0Saw0, t1Saw0, t0Saw1, t1Saw1, t2)*1000  MUST be c8's integer multiple.
            2. chirp's slope more than 1mhz/1us.
            3. t0Saw0, t1Saw0, t0Saw0, t1Saw0, t2, each of them should < 1ms.  so we can assume all channel's dt=1, that means 8ns. 
            why there is "1ms"?  Because our maximum step number is 2^17-1, and every step is assumed as 8ns, so (2^17-1)*8ns = 1ms approximately. 
            4. Assume t0Saw0 > 0.
            5. if t0Saw1=0, then t1Saw1 will be ignored.
            6. t0Saw0+t1Saw0+t0Saw1+t1Saw1+t2 = n*(120ns), to align adc sampling.
            7. single frequency mode setting: FM=0;
 */
void fmcwConfig_dualSaw(float fstart,uint32 fmSaw0,uint32 t0Saw0,uint32 t1Saw0,uint32 fmSaw1,uint32 t0Saw1,uint32 t1Saw1,uint32 t2,uint32 chirpNumber);

/**
 * @brief   fmcw enable mode.
 * @param   startMode: fmcw_en select. 1'h1: from data_sample module. 1'h0: from register.
 * @param   chirpMode: Chirp mode. 1 : single mode. 0 : continue mode.
 * @return  None.
 * @note
 */
void fmcwEnmode(int32 startMode, int32 chirpMode);
void waitFmcwcycEnd(void);

/**
 * @brief   tdMimo.
 *          t0,t1       != 0  channelNum=2
 *          t0,t1,t2    != 0  channelNum=3
 *          t0,t1,t2,t3 != 0  channelNum=4
 * @param   t0:.
 * @param   t1:.
 * @param   t2:.
 * @return  None.
 * @note
 */
void tdMimo(uint32 t0,uint32 t1,uint32 t2);

#endif
